<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>20、挂载生命周期</title>
</head>
<body>
    <div id="test"></div>

    <script type="text/javascript" src="../js/react.development.js"></script>
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/javascript" src="../js/prop-types.js"></script>
    
    <script type="text/babel"> 
        /*
            更新线：
                1. setState -> shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate
                2. forceUpdate -> componentWillUpdate -> render -> componentDidUpdate
                3. 父组件render -> componentWillReceiveProps -> shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate
        */
       /*
            常用的阶段：
                1. componentDidMount：执行初始化的事，如：开启定时器、发送网络请求、订阅消息
                2. componentWillUnmount：关闭定时器，取消订阅
       */
        /*
            新版本与旧版本的区别：
                1. 新版本中，旧版本的钩子函数仍然能用
                2. componentWillMount、componentWillUpdate、componentWillReceiveProps三个钩子函数前需要加UNSAFE_
                3. 废除三个钩子componentWillMount、componentWillUpdate、componentWillReceiveProps，
                   新增两个钩子getDerivedStateFromProps、getSnapshotBeforeUpdate
        */
        class Count extends React.Component{
            // 1. 构造函数
            constructor(props){
                console.log('Count---constructor')
                super(props)
                this.state = {count:0}
            }
            // 2. 将要被挂载
            componentWillMount(){
                console.log('Count---componentWillMount')
            }
            // 3. 
            render(){
                console.log('Count---render')
                const {count} = this.state
                return(
                    <div>
                        <h2>当前求和为:{this.state.count}</h2>
                        <button onClick={this.add}>点我+1</button>
                        <button onClick={this.death}>卸载组件</button>
                        <button onClick={this.force}>强制更新，不修改数据更新界面</button>
                    </div>
                )
            }
            // 4. 挂载完成
            componentDidMount(){
                console.log('Count---componentDidMount')
            }

            // 5. 将要卸载
            componentWillUnmount(){
                console.log('Count---componentWillUnmount')
            }

            // 6. 组件是否更新，返回boolean，如果为true，则更新，如果为false，则不更新
            // 不写这个函数时，将会自动增加一个返回值为true的此函数
            shouldComponentUpdate(){
                console.log('Count---shouldCompoentUpdate')
                return true
            }

            // 7. 组件将要更新
            componentWillUpdate(){
                console.log('Count---componentWillUpdate')
            }

            // 8. 组件更细完毕
            componentDidUpdate(){
                console.log('Count---componentDidUpdate')
            }


            add = ()=> {
                const {count} = this.state
                this.setState({count: count + 1})
            }

            death = () => {
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }

            force = () => {
                this.forceUpdate()
            }
        }

        class A extends React.Component{
            state = {carName: '奔驰'}
            render(){
                return(
                    <div>
                        <div>我是A组件</div>
                        <button onClick={this.changeCar}>换车</button>
                        <B carName={this.state.carName} />    
                    </div>
                )
            }
            changeCar = () => {
                this.setState({carName:'奥拓'})
            }
        }

        class B extends React.Component{
            // 第一次运行不会执行，传入参数改变时执行
            componentWillReceiveProps(props){
                console.log('B---componentWillReceiveProps',props)
            }
            render(){
                return (
                    <div>
                        我是B组件，接收到的车是：{this.props.carName}
                    </div>
                )
            }
        }
        ReactDOM.render(<A />,document.getElementById('test'))
    </script>
</body>
</html>